Conversation
|
CodeAnt AI is running Incremental review |
🏁 CodeAnt Quality Gate ResultsCommit: ✅ Overall Status: PASSEDQuality Gate Details
|
|
|
||
| if (response.repos) { | ||
| const sortedRepos = (response.repos || []).sort( | ||
| (a, b) => new Date(b.pushed_at) - new Date(a.pushed_at) |
There was a problem hiding this comment.
Suggestion: The date comparator subtracts new Date(...) values directly, which produces NaN for invalid or missing timestamps and makes sorting unreliable. Use parsed timestamps with a numeric fallback so repos are deterministically ordered even when pushed_at is absent. [logic error]
Severity Level: Major ⚠️
- ⚠️ listRepos may not sort repositories by latest push time.
- ⚠️ Repositories missing pushed_at can appear in inconsistent order.
- ⚠️ Downstream consumers relying on order get unreliable results.| (a, b) => new Date(b.pushed_at) - new Date(a.pushed_at) | |
| (a, b) => (Date.parse(b.pushed_at) || 0) - (Date.parse(a.pushed_at) || 0) |
Steps of Reproduction ✅
1. In a Node.js script, monkey-patch global `fetch` (used inside
`src/utils/fetchApi.js:4-25`) so that `response.json()` resolves to an object like `{
repos: [ { name: 'r1', full_name: 'org/r1', pushed_at: '2024-01-01T00:00:00Z' }, { name:
'r2', full_name: 'org/r2' }, { name: 'r3', full_name: 'org/r3', pushed_at:
'2024-02-01T00:00:00Z' } ] }`, where one repo lacks `pushed_at`.
2. Import `listRepos` from `src/scans/listRepos.js:13` in that script via `import {
listRepos } from './src/scans/listRepos.js';`.
3. Call `await listRepos('acme-org')`, which obtains the mocked response at
`src/scans/listRepos.js:15-17`, passes the `if (response.repos)` check at line 23, and
then sorts using `(response.repos || []).sort((a, b) => new Date(b.pushed_at) - new
Date(a.pushed_at))` at lines 24-26.
4. For the repo without `pushed_at`, `new Date(undefined)` yields an invalid Date whose
numeric value is `NaN`, so the comparator sometimes returns `NaN` instead of a
negative/zero/positive number; as a result, comparisons involving that repo treat it as
equal to others, and the final `sortedRepos` array returned at line 27 is not reliably
ordered by actual last push time, especially once multiple repos have missing or malformed
timestamps.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/scans/listRepos.js
**Line:** 25:25
**Comment:**
*Logic Error: The date comparator subtracts `new Date(...)` values directly, which produces `NaN` for invalid or missing timestamps and makes sorting unreliable. Use parsed timestamps with a numeric fallback so repos are deterministically ordered even when `pushed_at` is absent.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.| const normalized = { ...item }; | ||
| normalized.file_path = extractRelativeFilePath(item.file_path || item.path || item.filename || 'unknown'); | ||
| normalized.line_number = item.line_number || item.start_line || item.line || 1; | ||
| normalized.file_line_range = [normalized.line_number]; |
There was a problem hiding this comment.
Suggestion: The normalization logic always overwrites file_line_range with a single-line array, which drops valid multi-line ranges coming from scanners (especially IaC checks). Preserve the incoming range when present so callers can correctly display the full affected span. [logic error]
Severity Level: Major ⚠️
- ⚠️ Advanced IaC issues lose multi-line `file_line_range` spans.
- ⚠️ Downstream tools cannot show full misconfiguration blocks.| normalized.file_line_range = [normalized.line_number]; | |
| normalized.file_line_range = | |
| Array.isArray(item.file_line_range) && item.file_line_range.length > 0 | |
| ? item.file_line_range | |
| : [normalized.line_number]; |
Steps of Reproduction ✅
1. Import and call `fetchIacResults(repo, commitId)` exported at
`src/scans/fetchAdvancedScanResults.js:318-319`, which internally calls
`fetchAdvancedScanResults(repo, commitId, ADVANCED_RESULT_TYPES.IAC)` at
`src/scans/fetchAdvancedScanResults.js:202-204`.
2. In `fetchAdvancedScanResults`, when `resultType === ADVANCED_RESULT_TYPES.IAC`, the
response from `/extension/scans2/fetch-advanced-results` is flattened in the IAC branch at
`src/scans/fetchAdvancedScanResults.js:241-270`; each failed check is turned into an
object with `file_line_range: check.file_line_range || [1]` at lines `253-254`, preserving
any multi-line ranges returned by the scanner.
3. After flattening, the code normalizes all items via
`resultsData.filter(Boolean).map((item) => normalizeAdvancedIssue(item, resultType))` at
`src/scans/fetchAdvancedScanResults.js:279-280`, which calls `normalizeAdvancedIssue`
defined at `src/scans/fetchAdvancedScanResults.js:147-192`.
4. Inside `normalizeAdvancedIssue`, the snippet at
`src/scans/fetchAdvancedScanResults.js:154-155` overwrites `file_line_range` with
`[normalized.line_number]`, so an IaC issue that originally had `file_line_range: [10,
20]` from the scanner is returned to callers with `file_line_range: [10]`, losing the
multi-line span; a future consumer that wants to highlight the full affected range
(similar to how `fetchScanResults` sets `file_line_range` at
`src/scans/fetchScanResults.js:92`) will only know about the first line.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/scans/fetchAdvancedScanResults.js
**Line:** 155:155
**Comment:**
*Logic Error: The normalization logic always overwrites `file_line_range` with a single-line array, which drops valid multi-line ranges coming from scanners (especially IaC checks). Preserve the incoming range when present so callers can correctly display the full affected span.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.| reason_for_dismiss: dismissInfo.reason_for_dismiss || '', | ||
| comment_for_dismiss: dismissInfo.comment_for_dismiss || '', |
There was a problem hiding this comment.
Suggestion: dismissInfo is used as an object without null checks, so a null/undefined entry in response.data will throw when accessing dismissal fields and fail the whole operation. Use optional access with defaults to avoid crashing on partial backend data. [null pointer]
Severity Level: Major ⚠️
- ❌ Dismissed alerts fetch fails on any null dismissal entry.
- ⚠️ All valid dismissed alerts lost due to single bad record.| reason_for_dismiss: dismissInfo.reason_for_dismiss || '', | |
| comment_for_dismiss: dismissInfo.comment_for_dismiss || '', | |
| reason_for_dismiss: dismissInfo?.reason_for_dismiss || '', | |
| comment_for_dismiss: dismissInfo?.comment_for_dismiss || '', |
Steps of Reproduction ✅
1. Any future caller (e.g. a scansv2 CLI flow) invokes `fetchDismissedAlerts(repo)`
defined in `src/scans/fetchDismissedAlerts.js:13`, which internally calls
`fetchApi('/extension/scans2/dismiss-alerts/get', 'POST', { repo, analysis_type })` at
lines 15–18.
2. The backend responds with JSON parsed by `fetchApi` (`src/utils/fetchApi.js:4–37`),
returning an object where `data` contains at least one entry whose value is `null` or
`undefined`, e.g. `{ "some/file.js||::||code||::||T1": null }`.
3. In `fetchDismissedAlerts`, the code at `src/scans/fetchDismissedAlerts.js:28–32`
executes `const dismissData = response.data || {};` and then `for (const [issueKey,
dismissInfo] of Object.entries(dismissData))`; for the malformed entry, `dismissInfo` is
`null`/`undefined`.
4. When constructing `dismissedAlerts.push({ ... })` at lines 43–52, accessing
`dismissInfo.reason_for_dismiss` and `dismissInfo.comment_for_dismiss` at lines 50–51
throws a `TypeError` ("Cannot read properties of null/undefined"), which is caught by the
`try/catch` at lines 14–57, causing the whole function to return `{ success: false, error:
error.message || 'Failed to fetch dismissed alerts' }` and preventing any dismissed alerts
from being returned.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/scans/fetchDismissedAlerts.js
**Line:** 50:51
**Comment:**
*Null Pointer: `dismissInfo` is used as an object without null checks, so a null/undefined entry in `response.data` will throw when accessing dismissal fields and fail the whole operation. Use optional access with defaults to avoid crashing on partial backend data.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.|
CodeAnt AI Incremental review completed. |
|
CodeAnt AI is running the review. |
Sequence DiagramThis diagram shows how the new scans center validates the CLI connection, discovers repositories, and loads scan history and results (including advanced findings and dismissed alerts) for a selected repository and commit. sequenceDiagram
participant User
participant ScansCenter
participant CodeAntAPI
User->>ScansCenter: Open scans center
ScansCenter->>CodeAntAPI: Validate connection
CodeAntAPI-->>ScansCenter: Return organizations and user email
ScansCenter->>CodeAntAPI: List repositories for selected organization
CodeAntAPI-->>ScansCenter: Return repository list
User->>ScansCenter: Select repository and commit
ScansCenter->>CodeAntAPI: Get scan history for repository
CodeAntAPI-->>ScansCenter: Return scan runs
ScansCenter->>CodeAntAPI: Fetch scan and advanced results for repo and commit
ScansCenter->>CodeAntAPI: Fetch dismissed alerts for repo
CodeAntAPI-->>ScansCenter: Return issues and dismissed alerts
Generated by CodeAnt AI |
| if (response.last_analysis_results !== undefined) { | ||
| return { | ||
| success: true, | ||
| repo: response.repo, |
There was a problem hiding this comment.
Suggestion: Returning repo: response.repo can produce undefined when the backend does not echo the repository name, which breaks the function's documented contract. Use the input repo as fallback to keep output stable. [possible bug]
Severity Level: Major ⚠️
- ⚠️ Scan history consumers may see missing repo identifier.
- ⚠️ Scans center history view could mislabel or lose repo context.| repo: response.repo, | |
| repo: response.repo || repo, |
Steps of Reproduction ✅
1. In a test harness, mock `fetchApi` from `src/utils/fetchApi.js:4` so that when
`getScanHistory` calls it with endpoint `/extension/scans2/get-scan-history`
(`src/scans/getScanHistory.js:16`), it resolves to `{ last_analysis_results: [], status:
'success' }` and does not include a `repo` property.
2. Import and call `getScanHistory('org/repo-name')` from `src/scans/getScanHistory.js:14`
with this mock in place.
3. The function passes the mock response through the `if (response.last_analysis_results
!== undefined)` branch at `src/scans/getScanHistory.js:22-27` and constructs the result
object using `repo: response.repo` at line 25.
4. Inspect the returned value and observe that `result.repo` is `undefined` despite the
JSDoc contract at `src/scans/getScanHistory.js:8-11` documenting `repo: "org/repo-name"`;
this breaks the documented output shape whenever the backend omits the `repo` field, which
is a realistic scenario since no other client code in this repo depends on the server
echoing the repo name and other scan endpoints (e.g. `fetchScanResults` at
`src/scans/fetchScanResults.js:54-99`) do not expose `repo` at all.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/scans/getScanHistory.js
**Line:** 25:25
**Comment:**
*Possible Bug: Returning `repo: response.repo` can produce `undefined` when the backend does not echo the repository name, which breaks the function's documented contract. Use the input `repo` as fallback to keep output stable.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.| break; | ||
| case ADVANCED_RESULT_TYPES.DEAD_CODE: | ||
| normalized.check_name = | ||
| item.name || item.function_name || item.symbol_name || item.description || 'Unused code detected'; |
There was a problem hiding this comment.
Suggestion: Dead-code entries generated by flattenDeadCode already include a specific check_name, but the dead-code normalization ignores that field and overwrites it with a generic fallback, causing issue names to lose important context. Preserve item.check_name during normalization. [logic error]
Severity Level: Major ⚠️
- ⚠️ Dead-code scan labels become generic or lose rule context.
- ⚠️ Scans UI may mislead users about unused items severity.| item.name || item.function_name || item.symbol_name || item.description || 'Unused code detected'; | |
| item.check_name || item.name || item.function_name || item.symbol_name || item.description || 'Unused code detected'; |
Steps of Reproduction ✅
1. In a consumer (CLI or UI), import `fetchDeadCodeResults` from
`src/scans/fetchAdvancedScanResults.js`, where it is exported at lines 321–322; Grep over
the repo shows no current internal callers, so this is a new public API intended for the
scans center.
2. Mock `fetchApi` (`src/utils/fetchApi.js:1–44`) so that `fetchAdvancedScanResults`
(defined at `src/scans/fetchAdvancedScanResults.js:202–307`) is invoked with `resultType =
'dead_code'` and returns `{ status: 'success', dead_code: { python_dead_code: [...],
js_dead_code: {...}, extra_dead_code: {...} } }` in the shape expected by
`flattenDeadCode` at lines 42–141.
3. When `fetchAdvancedScanResults` executes the dead-code branch at lines 228–231, it
calls `flattenDeadCode`, which emits flat issue objects with rich `check_name` values such
as `Unused ${issueType}: ${name}` (lines 67–77), `'Unused file'` (lines 85–93), `'Unused
export: ${exp.name}'` (lines 104–113), or Sonar-style descriptions from
`EXTRA_DEAD_CODE_MESSAGES` (lines 124–136).
4. The flat array is then normalized via `normalizeAdvancedIssue` at
`src/scans/fetchAdvancedScanResults.js:147–191`; in the `ADVANCED_RESULT_TYPES.DEAD_CODE`
case (lines 182–185), the statement `normalized.check_name = item.name ||
item.function_name || item.symbol_name || item.description || 'Unused code detected';`
overwrites the existing `item.check_name`, so callers of `fetchDeadCodeResults` see
generic labels like `'Unused code detected'` or bare symbol names instead of the more
descriptive dead-code messages produced by `flattenDeadCode`.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/scans/fetchAdvancedScanResults.js
**Line:** 184:184
**Comment:**
*Logic Error: Dead-code entries generated by `flattenDeadCode` already include a specific `check_name`, but the dead-code normalization ignores that field and overwrites it with a generic fallback, causing issue names to lose important context. Preserve `item.check_name` during normalization.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.|
|
||
| // Filter secrets false positives | ||
| if (resultType === ADVANCED_RESULT_TYPES.SECRETS) { | ||
| issues = issues.filter((issue) => issue.confidence_score?.toLowerCase() !== 'false_positive'); |
There was a problem hiding this comment.
Suggestion: The secrets false-positive filter calls .toLowerCase() directly on confidence_score, which will throw at runtime when the backend sends a non-string value (for example numeric confidence). Normalize the value to a string before comparing. [type error]
Severity Level: Critical 🚨
- ❌ Secrets advanced scan crashes when confidence_score is non-string.
- ⚠️ Scans center cannot reliably display secrets findings and status.| issues = issues.filter((issue) => issue.confidence_score?.toLowerCase() !== 'false_positive'); | |
| issues = issues.filter((issue) => String(issue.confidence_score || '').toLowerCase() !== 'false_positive'); |
Steps of Reproduction ✅
1. In a Node test or REPL, import `fetchSecretsResults` from
`src/scans/fetchAdvancedScanResults.js` where it is exported at lines 315–316.
2. Mock `fetchApi` from `src/utils/fetchApi.js:1–44` so that `fetchAdvancedScanResults`
(defined at `src/scans/fetchAdvancedScanResults.js:202–307`) receives a JSON response like
`{ status: 'success', secrets: [ { file_path: 'foo.js', line_number: 10, confidence_score:
0.9 } ] }` when posting to `/extension/scans2/fetch-advanced-results`.
3. Call `await fetchSecretsResults('org/repo',
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')`; execution flows into the secrets branch at
`src/scans/fetchAdvancedScanResults.js:228–231`, sets `resultsData = response.secrets`,
builds the `issues` array via `normalizeAdvancedIssue` at lines 147–191, and then reaches
the secrets false-positive filter at lines 294–296.
4. At `src/scans/fetchAdvancedScanResults.js:295–296`, the expression
`issue.confidence_score?.toLowerCase() !== 'false_positive'` attempts to call
`.toLowerCase()` on the numeric `confidence_score` (0.9), causing a runtime `TypeError:
issue.confidence_score.toLowerCase is not a function` and making `fetchSecretsResults`
reject instead of returning scan results for the advanced secrets view.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/scans/fetchAdvancedScanResults.js
**Line:** 296:296
**Comment:**
*Type Error: The secrets false-positive filter calls `.toLowerCase()` directly on `confidence_score`, which will throw at runtime when the backend sends a non-string value (for example numeric confidence). Normalize the value to a string before comparing.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.| if (file_path.endsWith('/security_issues.json')) { | ||
| file_path = file_path.replace('/security_issues.json', ''); | ||
| } |
There was a problem hiding this comment.
Suggestion: Dismissed alert paths are only stripped for /security_issues.json, but scan results support other suffixes too; this creates a path mismatch for anti-pattern/docstring/complex-function dismissals and prevents proper re-matching. Strip all known scan-result suffixes consistently. [logic error]
Severity Level: Critical 🚨
- ❌ Dismissed anti-pattern alerts fail to re-associate with issues.
- ❌ Dismissed docstring alerts fail to re-associate with issues.
- ❌ Dismissed complex-function alerts fail to re-associate with issues.
- ⚠️ Users see previously dismissed non-security findings as active again.
- ⚠️ Central scans center behavior inconsistent across different scan result types.| if (file_path.endsWith('/security_issues.json')) { | |
| file_path = file_path.replace('/security_issues.json', ''); | |
| } | |
| file_path = file_path.replace(/\/(security_issues|anti_patterns|docstring|complex_functions)\.json$/, ''); |
Steps of Reproduction ✅
1. A consumer of this package calls `fetchAntiPatternsResults(repo, commitId)` from
`src/scans/fetchScanResults.js:108-109`. This function delegates to `fetchScanResults()`
with `resultType = 'anti_patterns'`.
2. Inside `fetchScanResults()` (`src/scans/fetchScanResults.js:54-99`), each server path
key like `org/repo/<commit>/path/to/file.py/anti_patterns.json` is converted to a clean
`file_path` via `extractCleanPath(fullPath, commitId, fileSuffix)` (`lines 24-44`) using
`fileSuffix = RESULT_FILE_SUFFIXES[resultType]` (`lines 10-15`). For `anti_patterns`, this
strips the `/anti_patterns.json` suffix so issues are emitted with `file_path =
'path/to/file.py'`.
3. For the same repository and scan type, the consumer calls `fetchDismissedAlerts(repo,
'anti_patterns')` from `src/scans/fetchDismissedAlerts.js:13-18`. The server returns
dismissed-alert keys in the format described in the header comment (`lines 6-8`), where
the first segment is the same full scan-result path used in `fetchScanResults`.
4. In `fetchDismissedAlerts`, the code at `src/scans/fetchDismissedAlerts.js:31-48` splits
each `issueKey` and assigns `file_path = parts[0]`. It only strips `/security_issues.json`
when `file_path.endsWith('/security_issues.json')` (`lines 39-41`), leaving
`/anti_patterns.json`, `/docstring.json`, or `/complex_functions.json` intact for other
result types. As a result, dismissed alerts for anti-patterns/docstring/complex-functions
use `file_path` values like `path/to/file.py/anti_patterns.json`, which do not match the
normalized `file_path` values `path/to/file.py` produced by `fetchScanResults`. Any
downstream logic that matches issues and dismissals on `(file_path, test_id)` will fail to
re-associate dismissed alerts for these non-security scan types, even though the same
files/issues are involved.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/scans/fetchDismissedAlerts.js
**Line:** 39:41
**Comment:**
*Logic Error: Dismissed alert paths are only stripped for `/security_issues.json`, but scan results support other suffixes too; this creates a path mismatch for anti-pattern/docstring/complex-function dismissals and prevents proper re-matching. Strip all known scan-result suffixes consistently.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.|
CodeAnt AI finished running the review. |
|
CodeAnt AI is running Incremental review |
| ce(Text, { color: 'gray' }, | ||
| (issue.file_path || 'unknown') + (issue.line_number ? `:${issue.line_number}` : '')), | ||
| ce(Text, null, | ||
| issue.check_name || issue.issue_text || issue.message || '') |
There was a problem hiding this comment.
Suggestion: Dismissed-alert items from fetchDismissedAlerts do not provide check_name, issue_text, or message, so this renderer shows blank issue text. Add fallbacks for dismissed fields to avoid empty result rows. [logic error]
Severity Level: Major ⚠️
- ⚠️ Dismissed alerts list shows blank descriptions for each finding.
- ⚠️ Harder to understand which rule each dismissal corresponds to.| issue.check_name || issue.issue_text || issue.message || '') | |
| issue.check_name || issue.issue_text || issue.message || issue.test_id || issue.type || issue.reason_for_dismiss || 'Dismissed finding') |
Steps of Reproduction ✅
1. Run the CLI with the `scan-center` command defined in `src/index.js:21-26`, which
renders the `ScanCenter` component to browse scan results.
2. Select a connection and repository (handled by `validateConnectionOnMount` in
`src/scanCenter/validateConnectionOnMount.js:3-14` and
`handleSelectConnection`/`listRepos` in `src/scanCenter/handleSelectConnection.js:3-13`
and `src/scans/listRepos.js:13-27`), then choose a scan from the SELECT_SCAN view
(`src/components/ScanCenter.js:270-301`).
3. In the SELECT_RESULT_TYPE menu (`src/components/ScanCenter.js:304-321`), choose either
"Dismissed Alerts" or "Dismissed Secrets", whose result types are defined in
`RESULT_TYPES` at `src/components/ScanCenter.js:34-35` with values `dismissed_alerts` and
`dismissed_secrets`.
4. The selection triggers `handleSelectResultType`
(`src/scanCenter/handleSelectResultType.js:5-25`), which for these result types calls
`fetchDismissedAlerts` (`src/scans/fetchDismissedAlerts.js:13-55`) and wraps
`r.dismissedAlerts` into `res.issues`; each dismissed issue object only contains
`file_path`, `context_code_block`, `test_id`, `line_number`, `type`, `issue_key`,
`reason_for_dismiss`, and `comment_for_dismiss` (no `check_name`, `issue_text`, or
`message`), so when `ResultsView` renders rows at `src/components/ScanCenter.js:106-115`
the description `Text` uses `issue.check_name || issue.issue_text || issue.message || ''`
and resolves to an empty string for every dismissed finding, producing result rows with a
severity tag and file path but a blank description.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/components/ScanCenter.js
**Line:** 115:115
**Comment:**
*Logic Error: Dismissed-alert items from `fetchDismissedAlerts` do not provide `check_name`, `issue_text`, or `message`, so this renderer shows blank issue text. Add fallbacks for dismissed fields to avoid empty result rows.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| setLoadingMsg(`Loading scan history for ${item.value.full_name}…`); | ||
| const res = await getScanHistory(item.value.full_name); |
There was a problem hiding this comment.
Suggestion: The repository identifier sent to getScanHistory assumes full_name always exists, but the UI allows selecting repos that may only have name. This can pass undefined to the API and fail loading scan history. [logic error]
Severity Level: Major ⚠️
- ❌ ScanCenter cannot load history for name-only repositories.
- ⚠️ Users blocked from viewing past scans for some repos.| setLoadingMsg(`Loading scan history for ${item.value.full_name}…`); | |
| const res = await getScanHistory(item.value.full_name); | |
| const repoFullName = item.value.full_name || item.value.name; | |
| setLoadingMsg(`Loading scan history for ${repoFullName}…`); | |
| const res = await getScanHistory(repoFullName); |
Steps of Reproduction ✅
1. Run the CLI so it renders the ScanCenter component defined in
`src/components/ScanCenter.js:156-201`, which orchestrates the multi-step scan flow.
2. From the "Select a connection" step, pick any connection; `handleSelectConnection` at
`src/scanCenter/handleSelectConnection.js:3-13` calls `listRepos()`
(`src/scans/listRepos.js:13-27`) and stores `response.repos` into the `repos` state.
3. Ensure the backend returns at least one repository object where `name` is set but
`full_name` is absent (the UI is explicitly coded to allow this via `.filter((r) => r &&
(r.name || r.full_name))` and `label: r.name || r.full_name` in
`src/components/ScanCenter.js:248-253`). This repo shows up as a selectable item in the
"Select a repository" list with `value: r`.
4. Select that name-only repository in the "Select a repository" screen so `onSelect:
handleSelectRepo` at `src/components/ScanCenter.js:262-263` invokes `_handleSelectRepo`.
Inside `src/scanCenter/handleSelectRepo.js:3-7`, `setLoadingMsg` and `getScanHistory` both
read `item.value.full_name`, which is `undefined` for this repo, so `getScanHistory`
(`src/scans/getScanHistory.js:14-16`) posts `{ repo: undefined }` to
`/extension/scans2/get-scan-history` (even though the JSDoc at `getScanHistory.js:6`
states `repo` should be a full-name string). The request fails and `handleSelectRepo`
falls into the error branch at lines 8-11, showing `Failed to fetch scan history` instead
of loading history for that repository.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/scanCenter/handleSelectRepo.js
**Line:** 6:7
**Comment:**
*Logic Error: The repository identifier sent to `getScanHistory` assumes `full_name` always exists, but the UI allows selecting repos that may only have `name`. This can pass `undefined` to the API and fail loading scan history.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| return; | ||
| } | ||
| const history = res.scanHistory || []; | ||
| process.stderr.write('SCAN_HISTORY_SAMPLE: ' + JSON.stringify(history.slice(0, 15), null, 2) + '\n'); |
There was a problem hiding this comment.
Suggestion: Writing raw scan history to stderr on every selection leaks potentially sensitive repository scan metadata and pollutes CLI output; this debug logging should be disabled by default. [security]
Severity Level: Major ⚠️
- ⚠️ Scan history metadata printed to stderr every repo selection.
- ⚠️ CI logs may leak repository scan context unintentionally.| process.stderr.write('SCAN_HISTORY_SAMPLE: ' + JSON.stringify(history.slice(0, 15), null, 2) + '\n'); | |
| if (process.env.CODEANT_DEBUG_SCAN_HISTORY === '1') { | |
| process.stderr.write('SCAN_HISTORY_SAMPLE: ' + JSON.stringify(history.slice(0, 15), null, 2) + '\n'); | |
| } |
Steps of Reproduction ✅
1. Start the CLI and navigate into the ScanCenter flow so that `ScanCenter` from
`src/components/ScanCenter.js:156-201` is active and repositories have been loaded into
state via `handleSelectConnection` and `listRepos`.
2. Reach the "Select a repository" step where `ScanCenter` builds items from the `repos`
state (`src/components/ScanCenter.js:248-255`) and wires `onSelect: handleSelectRepo`
(`ScanCenter.js:262-263`) to delegate repository selection.
3. Select any repository whose scan history can be fetched successfully. This calls
`_handleSelectRepo` from `src/scanCenter/handleSelectRepo.js:3-7`, which awaits
`getScanHistory(item.value.full_name)` and, on success, assigns `const history =
res.scanHistory || [];` at line 12.
4. On every such successful selection, the debug statement at
`src/scanCenter/handleSelectRepo.js:13` executes
`process.stderr.write('SCAN_HISTORY_SAMPLE: ' + JSON.stringify(history.slice(0, 15), null,
2) + '\n');`, unconditionally dumping up to 15 scan history entries (including repository
identifiers, branches, commit SHAs, and timestamps used later in `ScanCenter.js:271-286`)
to stderr, where they appear in user terminals or CI logs without any opt-in control.Fix in Cursor | Fix in VSCode Claude
(Use Cmd/Ctrl + Click for best experience)
Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/scanCenter/handleSelectRepo.js
**Line:** 13:13
**Comment:**
*Security: Writing raw scan history to stderr on every selection leaks potentially sensitive repository scan metadata and pollutes CLI output; this debug logging should be disabled by default.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix|
CodeAnt AI Incremental review completed. |
CodeAnt-AI Description
Add an interactive scans center for browsing repository scan results
What Changed
scan-centercommand that guides users through connected organizations, repositories, scan history, and result types in one flowImpact
✅ Faster access to scan history✅ Clearer review of security findings✅ Restored dismissed alerts with saved context🔄 Retrigger CodeAnt AI Review
Details
💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.